home *** CD-ROM | disk | FTP | other *** search
/ Interactive Web Graphics with Shout 3D / Interactive Web Graphics With Shout 3D.iso / pc / Code / Chapter11 / ScanTheSkiesPanel.java < prev   
Text File  |  2000-07-26  |  7KB  |  250 lines

  1.  
  2. package applets;
  3.  
  4. import shout3d.*;
  5. import shout3d.core.*;
  6. import shout3d.math.*;
  7. import custom_nodes.*;  //for ScanTheSkiesDisplay
  8. import java.applet.*;  //for AudioClip
  9.  
  10.  
  11. public class ScanTheSkiesPanel extends Shout3DPanel implements DeviceObserver {
  12.    
  13.    
  14.  
  15.    //game state variables
  16.    boolean started = false;
  17.    boolean killed = false;
  18.  
  19.    
  20.    //screen pixels
  21.    int startPixelX;
  22.    int startPixelY;
  23.    
  24.    //heads-Up display
  25.    ScanTheSkiesDisplay display;
  26.    int score = 0;
  27.    double startTime;
  28.    int elapsedSeconds;
  29.       
  30.    //missile
  31.    int totalSeconds = 40;
  32.    float distance;
  33.    float speed = 10;  //10 meters per second
  34.    float startDistance = 10.f * totalSeconds;
  35.    Transform child;
  36.    Transform parent;
  37.    float[] missileAxisAngle = new float[4];
  38.    float[] missileEulers = new float[3];
  39.    Quaternion missileQ = new Quaternion();
  40.    
  41.    //gun
  42.    Transform gun;
  43.    float[] gunAxisAngle = new float[4];
  44.    float[] gunEulers = new float[3];
  45.    Quaternion gunQ = new Quaternion();
  46.    float headingSpeed = 0.0f;
  47.    float pitchSpeed = 0.0f;
  48.    Picker fire;
  49.  
  50.    //animated explosion
  51.    TimeSensor detonator;
  52.    Transform explosion;
  53.    float [] intersection = new float[3];
  54.    AudioClip gong;
  55.  
  56.  
  57.  
  58.  
  59.    //the constructor
  60.    public ScanTheSkiesPanel (Shout3DApplet applet){
  61.       super(applet);
  62.    }
  63.    
  64.  
  65.    public void customInitialize() {
  66.    
  67.       //get references to scene nodes
  68.       child = (Transform) getNodeByName("CHILD");
  69.       parent = (Transform) getNodeByName("PARENT");
  70.       detonator = (TimeSensor) getNodeByName("DETONATOR");
  71.       gun = (Transform) getNodeByName("GUN");
  72.       explosion = (Transform) getNodeByName("EXPLOSION");   
  73.       display = (ScanTheSkiesDisplay) getNodeByName("DISPLAY");   
  74.       gong = applet.getAudioClip(applet.getCodeBase(), "models/sounds/gong.au");
  75.             
  76.       //register observers
  77.       addDeviceObserver(this, "MouseInput", null);
  78.       getRenderer().addRenderObserver(this, null);
  79.       
  80.       //create a picker
  81.       fire = getNewPicker();
  82.       
  83.    }
  84.  
  85.  
  86.  
  87.    protected void finalize()  { 
  88.       removeDeviceObserver(this,"MouseInput");
  89.       getRenderer().removeRenderObserver(this);
  90.    }
  91.  
  92.  
  93.  
  94.    public boolean onDeviceInput(DeviceInput di, Object userData) {
  95.  
  96.       MouseInput mi = (MouseInput) di;
  97.       switch (mi.which) {
  98.       
  99.          case MouseInput.DOWN:
  100.          
  101.             if (started == false) {
  102.                //create missile to start
  103.                started = true;
  104.                newMissile();
  105.             }
  106.             
  107.             if (killed) {
  108.                //if killed, reset score
  109.                score = 0;
  110.                display.score.setValue(score);
  111.                killed = false;
  112.             }
  113.             
  114.             //in any case, store start of drag
  115.             startPixelX = mi.x;
  116.             startPixelY = mi.y;
  117.             return true;
  118.          
  119.          case MouseInput.DRAG:
  120.          
  121.             //set gun rotation speeds
  122.             //based on drag distances
  123.             int endPixelX = mi.x;
  124.             int endPixelY = mi.y;
  125.             int dragDistanceX = endPixelX - startPixelX;
  126.             int dragDistanceY = endPixelY - startPixelY;
  127.             headingSpeed = dragDistanceX/150f;
  128.             pitchSpeed = dragDistanceY/70f;
  129.             return true;
  130.  
  131.          
  132.          case MouseInput.UP:
  133.                
  134.             //store intersection point
  135.             fire.setPickInfo(Picker.POINT, true);
  136.  
  137.             //compute center of window
  138.             int centerPixelX = size().width/2;
  139.             int centerPixelY = size().height/2;
  140.  
  141.             //fire the picker ray
  142.             Node [] results = fire.pickClosest(centerPixelX, centerPixelY);
  143.  
  144.             //if ray hits something
  145.             if (results != null)  {
  146.  
  147.                //move explosion to intersection
  148.                //and detonate with sound
  149.                intersection = fire.getPickInfo(Picker.POINT);
  150.                explosion.translation.setValue(intersection);
  151.                detonator.start();         
  152.                gong.play();                 
  153.  
  154.                //increment the score
  155.                //and update the display
  156.                score++;
  157.                display.score.setValue(score);
  158.      
  159.                 //decrease missle start
  160.                 //distance by 10, but not
  161.                 //below 200 meters
  162.                 if (totalSeconds > 20) {
  163.                    totalSeconds--;
  164.                    startDistance = 10.0f * totalSeconds;
  165.                 }
  166.                 
  167.                 //launch a new missile
  168.                 newMissile();              
  169.             }
  170.              
  171.             //stop gun rotation   
  172.             headingSpeed = 0.0f;
  173.             pitchSpeed = 0.0f;
  174.             return true;
  175.    
  176.          
  177.       }//end of switch
  178.  
  179.       return false;
  180.             
  181.    }//end of onDeviceInput()
  182.  
  183.  
  184.    
  185.  
  186.    public void onPreRender (Renderer r, Object o) {
  187.       
  188.       //do nothing unless game is started
  189.       if (started) {
  190.          
  191.          //compute current distance
  192.          //of missile from player
  193.          float delta = speed/getFramesPerSecond();
  194.          distance = distance - delta;
  195.          
  196.          //end game if missile hits player
  197.          if (distance <= 0){
  198.          
  199.             display.shotClock.setValue(0);
  200.             killed = true;   
  201.             started = false;
  202.             totalSeconds = 40;
  203.             startDistance = 10.0f * totalSeconds;
  204.             return;
  205.          }
  206.          
  207.          //if missile still moving,
  208.          //update its position
  209.          child.translation.set1Value(2, -distance);
  210.          
  211.          //update gun rotation
  212.          float headingDelta = headingSpeed/getFramesPerSecond();
  213.          float pitchDelta = pitchSpeed/getFramesPerSecond();      
  214.          gunEulers[0] = gunEulers[0] + headingDelta;
  215.          gunEulers[1] = gunEulers[1] + pitchDelta;
  216.          gunQ.setEulers(gunEulers);
  217.          gunQ.getAxisAngle(gunAxisAngle);
  218.          gun.rotation.setValue(gunAxisAngle);
  219.          
  220.          //update shot clock         
  221.          double currentTime = getAbsoluteTime();
  222.          elapsedSeconds = (int)(currentTime - startTime);
  223.          display.shotClock.setValue(totalSeconds - elapsedSeconds);
  224.       
  225.    
  226.       }//end of if started  
  227.  
  228.    }//end of onPreRender()
  229.       
  230.  
  231.    private void newMissile() {
  232.    
  233.       //set random heading and pitch
  234.       missileEulers[0] =  (float) (Math.random() * 6.28);
  235.       missileEulers[1] = (float) (Math.random() * 6.28);      
  236.       missileQ.setEulers(missileEulers);
  237.       
  238.       //rotate missile to start position
  239.       missileQ.getAxisAngle(missileAxisAngle);
  240.       parent.rotation.setValue(missileAxisAngle);      
  241.       distance = startDistance;
  242.       child.translation.set1Value(2, -distance);
  243.       
  244.       //reset clock
  245.       startTime = getAbsoluteTime();            
  246.                
  247.    }//end of newMissile()
  248.  
  249.  
  250. } //end of class